/*******************************************************************************
  * 文件：Buzzer.c
  * 作者：zyz
  * 版本：v1.0.0
  * 日期：2020-07-16
  * 说明：蜂鸣器
*******************************************************************************/

/* 头文件 *********************************************************************/
#include "Buzzer.h"

/* 宏定义 *********************************************************************/
/* 类型定义 *******************************************************************/
/* 变量定义 *******************************************************************/

// Candy - Welcom
static const BuzzerTone_ts asCandyWelcom[] =
{
    { 3951,  60, 160,  0},
    { 3520, 140, 160, 10},
    { 3135,  60, 160,  0},
    { 4186, 230, 160,  0}
};

// Candy - Key press
static const BuzzerTone_ts asCandyKeyPress[] =
{
    { 3951,  50, 160,  0}
};

// Candy - Action not allowed
static const BuzzerTone_ts asCandyActionNotAllowed[] =
{
    { 3135,  5, 160,  0},
    { 3135,  5, 160,  0},
};

// Candy - Key lock on 
static const BuzzerTone_ts asCandyKeyLockOn[] =
{
    { 4186,  100, 160,  0}
};

// Candy - Slider press
static const BuzzerTone_ts asCandySliderPress[] =
{
    { 500,  20, 160,  0}
};

// Candy - Pause on
static const BuzzerTone_ts asCandyPauseOn[] =
{
    { 3729,  40, 160,  0},
    { 3729,  40, 160,  0},
    { 3729,  40, 160,  0}
};

// Candy - Spillage warning
static const BuzzerTone_ts asCandySpillageWarning[] =
{
    { 3591,  90, 160,  20   },
    { 3591,  90, 160,  1000 },
    { 3591,  90, 160,  20   },
    { 3591,  90, 160,  1000 },
    { 3591,  90, 160,  20   },
    { 3591,  90, 160,  1000 }
};

// Candy - Double global timer ended
static const BuzzerTone_ts asCandyDoubleGlobalTimerEnded[] =
{
    { 3591,  20, 160,  10   },
    { 3591,  20, 160,  10   },
    { 3591,  20, 160,  10   },
    { 3591,  20, 160,  10   },
    {    0,   0,   0,  250  }
};

// Candy - Goodbye
static const BuzzerTone_ts asCandyGoodbye[] =
{
    { 4186,  60, 160,  0   },
    { 3520, 130, 160, 10   },
    { 3951,  60, 160,  0   },
    { 3135, 200, 160,  0   }
};

// Candy - Start cooking
static const BuzzerTone_ts asCandyStartCooking[] =
{
    { 3951,  60, 160,  0   },
    { 3951,  60, 160,  0   }
};

// Candy - Cooking end
static const BuzzerTone_ts asCandyCookingEnd[] =
{
    { 3729,  60, 160,  10   },
    { 3729,  60, 160,  10   }
};

// Candy - Key lock off
static const BuzzerTone_ts asCandyKeyLockOff[] =
{
    { 4186,  60, 160,  0   }
};

// Candy - Pause off
static const BuzzerTone_ts asCandyPauseOff[] =
{
    { 3729,  60, 160,  0   }
};

// Candy - Spillage alarm
static const BuzzerTone_ts asCandySpillageAlarm[] =
{
    { 3951,  60, 160,  10   },
    { 3951,  60, 160,  10   },
    { 3951,  60, 160,  10   },
    { 3951,  60, 160,  10   },
    { 3951,  60, 160,  10   }
};

// 声音表
static const BuzzerSound_ts asSoundTable[eBUZZER_SOUND_SUM] =
{
    // 欢迎音
    { (BuzzerTone_ts *)asCandyWelcom,                   (U16)(ARRAY_SIZE(asCandyWelcom))            },
    { (BuzzerTone_ts *)asCandyKeyPress,                 (U16)(ARRAY_SIZE(asCandyKeyPress))          },
    { (BuzzerTone_ts *)asCandyActionNotAllowed,         (U16)(ARRAY_SIZE(asCandyActionNotAllowed))  },
    { (BuzzerTone_ts *)asCandyKeyLockOn,                (U16)(ARRAY_SIZE(asCandyKeyLockOn))         },
    { (BuzzerTone_ts *)asCandySliderPress,              (U16)(ARRAY_SIZE(asCandySliderPress))       },
    { (BuzzerTone_ts *)asCandyPauseOn,                  (U16)(ARRAY_SIZE(asCandyPauseOn))           },
    { (BuzzerTone_ts *)asCandySpillageWarning,          (U16)(ARRAY_SIZE(asCandySpillageWarning))   },
    { (BuzzerTone_ts *)asCandyDoubleGlobalTimerEnded,   (U16)(ARRAY_SIZE(asCandyDoubleGlobalTimerEnded)) },
    { (BuzzerTone_ts *)asCandyGoodbye,                  (U16)(ARRAY_SIZE(asCandyGoodbye))           },
    { (BuzzerTone_ts *)asCandyStartCooking,             (U16)(ARRAY_SIZE(asCandyStartCooking))      },
    { (BuzzerTone_ts *)asCandyCookingEnd,               (U16)(ARRAY_SIZE(asCandyCookingEnd))        },
    { (BuzzerTone_ts *)asCandyKeyLockOff,               (U16)(ARRAY_SIZE(asCandyKeyLockOff))        },
    { (BuzzerTone_ts *)asCandyPauseOff,                 (U16)(ARRAY_SIZE(asCandyPauseOff))          },
    { (BuzzerTone_ts *)asCandySpillageAlarm,            (U16)(ARRAY_SIZE(asCandySpillageAlarm))     },
};


// 蜂鸣器控制
static BuzzerControl_ts sBuzzerControl;

/* 函数声明 *******************************************************************/
/* 函数定义 *******************************************************************/

/*******************************************************************************
  * 函数名：Buzzer_Init
  * 功  能：初始化
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Buzzer_Init(void)
{
    // 初始化发声标志
    sBuzzerControl.bSounding = FALSE;
    // 初始化回调函数
    sBuzzerControl.pfEnablePower  = Hardware_BuzzerPowerSet;
    sBuzzerControl.pfEnableDriver = Hardware_EnablePWM;
    sBuzzerControl.pfSetPWM = Hardware_SetPWM;
    // 关闭输出
    sBuzzerControl.pfEnablePower(FALSE);
    sBuzzerControl.pfEnableDriver(FALSE);
    sBuzzerControl.pfSetPWM(0,0);
}

/*******************************************************************************
  * 函数名：Buzzer_Play
  * 功  能：发声
  * 参  数：BuzzerSound_te eSound - 声音
  *        BuzzerVolume_te eVol:音量
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Buzzer_Play(BuzzerSound_te eSound,BuzzerVolume_te eVol)
{
    // 确保参数正确
    if((eSound < eBUZZER_SOUND_SUM))
    {
        // 清除发声标志
        sBuzzerControl.bSounding = FALSE;
        // 关闭电源，使能驱动
        sBuzzerControl.pfEnablePower(FALSE);
        sBuzzerControl.pfSetPWM(0,0);
        sBuzzerControl.pfEnableDriver(TRUE);
        // 初始化控制参数
        sBuzzerControl.eSound = eSound;     // 声音
        sBuzzerControl.eVolume= eVol;       // 音量
        sBuzzerControl.u16ToneIndex = 0;    // 音调索引
        sBuzzerControl.u16TimeCount = 0;    // 时间计数
        // 设置发声标志
        sBuzzerControl.bSounding = TRUE;
    }
}

/*******************************************************************************
  * 函数名：Buzzer_TimingHandler
  * 功  能：定时处理
  * 参  数：无
  * 返回值：无
  * 说  明：定时1ms处理
*******************************************************************************/
void Buzzer_TimingHandler(void)
{
    BuzzerSound_ts *psSound = NULL;
    BuzzerTone_ts *psTone = NULL;

    // 发声
    if(sBuzzerControl.bSounding)
    {
        // 获取声音
        psSound = (BuzzerSound_ts *)&(asSoundTable[sBuzzerControl.eSound]);
        // 获取当前音调
        psTone = &(psSound->psTone[sBuzzerControl.u16ToneIndex]);

        // 开启时间、衰减时间、关闭时间都等于0时，切换下一个音调
        while((psTone->u16OnTime == 0) && (psTone->u16FadeTime == 0) && (psTone->u16OffTime == 0) 
                && (sBuzzerControl.u16ToneIndex < psSound->u16ToneNum))
        {
            // 获取下一个音调
            sBuzzerControl.u16ToneIndex++;
            psTone = &(psSound->psTone[sBuzzerControl.u16ToneIndex]);
        }

        // 播放音调
        if(sBuzzerControl.u16ToneIndex < psSound->u16ToneNum)
        {
            // 使能供电
            if(sBuzzerControl.u16TimeCount < psTone->u16OnTime)
            {
                sBuzzerControl.pfEnablePower(TRUE);
            }
            // 关闭供电
            else
            {
                sBuzzerControl.pfEnablePower(FALSE);
            }

            // 设置频率
            if(sBuzzerControl.u16TimeCount < (psTone->u16OnTime + psTone->u16FadeTime))
            {
                // 根据音量高低，选择占空比
                switch(sBuzzerControl.eVolume)
                {
                    case eBUZZER_VOL_LOW:
                        sBuzzerControl.pfSetPWM(psTone->u16Frequency,U8_BUZZER_VOLUME_LOW_DUTY);
                        break;
                    case eBUZZER_VOL_MED:
                        sBuzzerControl.pfSetPWM(psTone->u16Frequency,U8_BUZZER_VOLUME_MED_DUTY);
                        break;
                    case eBUZZER_VOL_HIGH:
                        sBuzzerControl.pfSetPWM(psTone->u16Frequency,U8_BUZZER_VOLUME_HIGH_DUTY);
                        break;
                    default:
                        sBuzzerControl.pfSetPWM(psTone->u16Frequency,U8_BUZZER_VOLUME_HIGH_DUTY);
                        break;
                }
            }
            // 关闭频率
            else
            {
                sBuzzerControl.pfSetPWM(0,0);
            }

            // 播放时间计数
            if(sBuzzerControl.u16TimeCount < (psTone->u16OnTime + psTone->u16FadeTime + psTone->u16OffTime))
            {
                sBuzzerControl.u16TimeCount++;
            }
            // 播放结束
            else
            {
                // 清零播放时间计数
                // 更新音调索引
                sBuzzerControl.u16TimeCount = 0;
                sBuzzerControl.u16ToneIndex++;
            }
        }
        // 音调播放完成
        else
        {
            // 清除发声标志
            sBuzzerControl.bSounding = FALSE;
            // 关闭输出
            sBuzzerControl.pfEnablePower(FALSE);
            sBuzzerControl.pfEnableDriver(FALSE);
            sBuzzerControl.pfSetPWM(0,0);
        }
    }
}

/***************************** 文件结束 ***************************************/
